﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Security.Cryptography;
using System.IO;
using System.Xml;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;
using System.Drawing;
using DocumentFormat.OpenXml.Packaging;
using System.Drawing.Imaging;
using docTissV2.Enumeradores;
using SchemasLib;

namespace docTissV2.Classes
{
    public static class AddinUtils
    {
        #region Atributos
        private static OleDbCommand cmd;
        #endregion

        #region Propriedades
        public static OleDbCommand Command
        {
            get
            {
                return cmd;
            }
        }

        public static Int32 UsuarioID { get; set; }
        public static string PrestadorNome { get; set; }
        public static string CPF_CNPJ { get; set; }
        public static TipoPrestador? TipoPrestador { get; set; }
        #endregion

        #region Métodos privados

        private static void AlteraValorTagCustomXml(XmlDocument xdoc, XmlNamespaceManager nsManager, string xPath, string valor)
        {
            try
            {
                if (valor != null && xPath != null)
                    xdoc.SelectSingleNode(xPath, nsManager).InnerText = valor;
            }
            catch (Exception) { }
        }

        #endregion

        #region Métodos publicos

        public static string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString().ToUpper();
        }

        public static string CalculateMD5Hash(Stream streamMensagem)
        {
            XmlDocument docMensagem = new XmlDocument();
            docMensagem.Load(streamMensagem);
            string input = "";
            input = docMensagem.DocumentElement.InnerText;

            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString().ToUpper();
        }

        /// <summary>
        /// Abre a Guia Selecionada
        /// </summary>
        /// <param name="filePath">Diretório da guia a ser aberta</param>
        public static void AbrirGuia(object filePath)
        {
            try
            {
                object mis = Globals.ThisAddIn._missing;
                object fake = false;
                Globals.ThisAddIn.Application.Documents.Open(ref filePath, ref fake, ref fake, ref mis, ref mis,
                                                            ref mis, ref mis, ref mis, ref mis, ref mis, ref mis,
                                                            ref mis, ref mis, ref mis, ref mis, ref mis);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            if (Globals.ThisAddIn.GerenciaGuiaCTP != null)
                if (!Globals.ThisAddIn.GerenciaGuiaCTP.Visible)
                    Globals.Ribbons.rbbDocTiss.tbtnGerenciarGuias.Checked = Globals.ThisAddIn.GerenciaGuiaCTP.Visible;
        }

        /// <summary>
        /// Fecha a Guia Selecionada
        /// </summary>
        /// <param name="filePath">Diretório da guia a ser fechada</param>
        public static void FecharGuia(object filePath)
        {
            try
            {
                object mis = Globals.ThisAddIn._missing;
                object promptToSaveChanges = WdSaveOptions.wdPromptToSaveChanges;
                //DocumentClass doc = Globals.ThisAddIn.Application.Documents.get_Item(ref filePath) as DocumentClass;
                //doc.Close(ref promptToSaveChanges, ref mis, ref mis);
            }
            catch (Exception) { }
        }

        public static void PreencheGuia(string pathGuia, DadosAutoPreencherGuia dadosAutoPreencher, TipoProfissional tipoProfissional)
        {
            XmlDocument xdoc = new XmlDocument();
            XmlDocument xmlMainDoc = new XmlDocument();

            using (WordprocessingDocument wdoc = WordprocessingDocument.Open(pathGuia, false))
            {
                xmlMainDoc.Load(wdoc.MainDocumentPart.GetStream());

                //Buscando o CustomXML referente a Guia
                foreach (CustomXmlPart cPart in wdoc.MainDocumentPart.CustomXmlParts)
                {
                    //Carrega a parte
                    xdoc.Load(cPart.GetStream());

                    //Encontrou?
                    if (xdoc.InnerXml.Contains("ans"))
                    {
                        XmlNamespaceManager nsManager = new XmlNamespaceManager(xdoc.NameTable);
                        nsManager.AddNamespace("ans", "http://www.ans.gov.br/padroes/tiss/schemas");
                        nsManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

                        string xPathCodigoPrestador = null;

                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.RegistroANS, dadosAutoPreencher.dadosGuia.RegistroANS);
                        switch (tipoProfissional)
                        {
                            case TipoProfissional.ProfissionalSolicitanteExecutante:
                            case TipoProfissional.ProfissionalSolicitante:
                                xPathCodigoPrestador = XMLUtils.BuscaXPathCodigoPrestadorExistente(dadosAutoPreencher.xPathSolicitante, xdoc, nsManager);
                                if (xPathCodigoPrestador != null)
                                {
                                    if (dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora != null && !dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora.Equals(""))
                                    {
                                        XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "codigoPrestadorNaOperadora");
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoPrestadorNaOperadora, dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora);
                                        xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CodigoPrestadorNaOperadora, TipoProfissional.ProfissionalSolicitante);
                                    }
                                    else
                                    {
                                        if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CPF");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CPF, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CPF, TipoProfissional.ProfissionalSolicitante);
                                        }
                                        else if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 14)
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CNPJ");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CNPJ, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CNPJ, TipoProfissional.ProfissionalSolicitante);
                                        }
                                    }
                                }
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.NomeContratado, dadosAutoPreencher.dadosGuia.NomeContratado);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.TipoLogradouro, dadosAutoPreencher.dadosGuia.TipoLogradouro);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Logradouro, dadosAutoPreencher.dadosGuia.Logradouro);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Numero, dadosAutoPreencher.dadosGuia.Numero);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Complemento, dadosAutoPreencher.dadosGuia.Complemento);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoIBGEMunicipio, dadosAutoPreencher.dadosGuia.CodigoIBGEMunicipio);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Municipio, dadosAutoPreencher.dadosGuia.Municipio);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoUF, dadosAutoPreencher.dadosGuia.CodigoUF);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Cep, dadosAutoPreencher.dadosGuia.Cep);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CNES, dadosAutoPreencher.dadosGuia.CNES);
                                if (dadosAutoPreencher.tipoGuia == TipoGuia.SP_SADT || dadosAutoPreencher.tipoGuia == TipoGuia.SP_SADT_Reapresentação)
                                {
                                    if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                    {
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.SiglaConselho, dadosAutoPreencher.dadosGuia.SiglaConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.NumeroConselho, dadosAutoPreencher.dadosGuia.NumeroConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.UFConselho, dadosAutoPreencher.dadosGuia.UFConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CBOS, dadosAutoPreencher.dadosGuia.CBOS);
                                    }
                                }
                                if (tipoProfissional == TipoProfissional.ProfissionalSolicitanteExecutante)
                                    goto case TipoProfissional.ProfissionalExecutante;
                                break;
                            case TipoProfissional.ProfissionalExecutante:
                                //if (dadosAutoPreencher.tipoGuia != TipoGuia.Consulta && dadosAutoPreencher.tipoGuia != TipoGuia.Consulta_Reapresentação)
                                //{
                                    xPathCodigoPrestador = XMLUtils.BuscaXPathCodigoPrestadorExistente(dadosAutoPreencher.xPathExecutante, xdoc, nsManager);
                                    if (xPathCodigoPrestador != null)
                                    {
                                        if (dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora != null && !dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora.Equals(""))
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "codigoPrestadorNaOperadora");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoPrestadorNaOperadora, dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CodigoPrestadorNaOperadora, TipoProfissional.ProfissionalExecutante);
                                        }
                                        else
                                        {
                                            if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                            {
                                                XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CPF");
                                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CPF, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                                xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CPF, TipoProfissional.ProfissionalExecutante);
                                            }
                                            else if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 14)
                                            {
                                                XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CNPJ");
                                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CNPJ, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                                xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CNPJ, TipoProfissional.ProfissionalExecutante);
                                            }
                                        }
                                    }
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NomeContratado, dadosAutoPreencher.dadosGuia.NomeContratado);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.TipoLogradouro, dadosAutoPreencher.dadosGuia.TipoLogradouro);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Logradouro, dadosAutoPreencher.dadosGuia.Logradouro);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Numero, dadosAutoPreencher.dadosGuia.Numero);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Complemento, dadosAutoPreencher.dadosGuia.Complemento);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoIBGEMunicipio, dadosAutoPreencher.dadosGuia.CodigoIBGEMunicipio);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Municipio, dadosAutoPreencher.dadosGuia.Municipio);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoUF, dadosAutoPreencher.dadosGuia.CodigoUF);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Cep, dadosAutoPreencher.dadosGuia.Cep);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CNES, dadosAutoPreencher.dadosGuia.CNES);
                                    if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                    {
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NomeProfissional, dadosAutoPreencher.dadosGuia.NomeContratado);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.SiglaConselho, dadosAutoPreencher.dadosGuia.SiglaConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NumeroConselho, dadosAutoPreencher.dadosGuia.NumeroConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.UFConselho, dadosAutoPreencher.dadosGuia.UFConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CBOS, dadosAutoPreencher.dadosGuia.CBOS);
                                    }
                                //}
                                break;
                            default:
                                break;
                        }
                        break;
                    }
                }
            }
            XMLUtils.SubstituiCustomXmlPart(pathGuia, "ans:registroANS", xdoc);
            XMLUtils.SubstituiMainDocumentPart(pathGuia, xmlMainDoc);
        }

        public static void AlteraLogoGuia(Image logotipo)
        {
            object mis = Globals.ThisAddIn._missing;
            object logoOperadoraCC = 1;
            if (logotipo != null)
            {
                string pathLogo = Path.GetTempFileName() + ".png";
                logotipo.Save(pathLogo, ImageFormat.Png);

                Globals.ThisAddIn.doc.ContentControls.get_Item(ref logoOperadoraCC).Range.InlineShapes.AddPicture(pathLogo, ref mis, ref mis, ref mis);
                Globals.ThisAddIn.IndexNumeroGuiaCC = 2;
            }
            else
            {
                Globals.ThisAddIn.doc.ContentControls.get_Item(ref logoOperadoraCC).Delete(true);
                Globals.ThisAddIn.IndexNumeroGuiaCC = 1;
            }
        }

        public static void AddContentControlToRange(Microsoft.Office.Interop.Word.Range range, string nodeXPath, Microsoft.Office.Core.CustomXMLPart customXMLPart)
        {
            object refCCRange = range;
            range.Select();
            Microsoft.Office.Interop.Word.ContentControl cc = range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref refCCRange);
            cc.SetPlaceholderText(null, null, "Editar");
            Microsoft.Office.Core.CustomXMLNode nodeMapping = customXMLPart.DocumentElement.SelectSingleNode(nodeXPath);

            cc.XMLMapping.SetMappingByNode(nodeMapping);
        }

        public static void AddContentControlToRange(Microsoft.Office.Interop.Word.ContentControl oldCC, Microsoft.Office.Interop.Word.Range range, string nodeXPath, Microsoft.Office.Core.CustomXMLPart customXMLPart)
        {
            object refCCRange = range;
            range.Select();
            Microsoft.Office.Interop.Word.ContentControl cc = range.ContentControls.Add(oldCC.Type, ref refCCRange);//ref Globals.ThisAddIn._missing);

            if (cc.Type == WdContentControlType.wdContentControlDropdownList)
            {
                foreach (ContentControlListEntry item in oldCC.DropdownListEntries)
                {
                    cc.DropdownListEntries.Add(item.Text, item.Value, item.Index);
                }
            }
            else if (cc.Type == WdContentControlType.wdContentControlDate)
            {
                cc.DateStorageFormat = oldCC.DateStorageFormat;
                cc.DateDisplayLocale = oldCC.DateDisplayLocale;
                cc.DateDisplayFormat = oldCC.DateDisplayFormat;
                cc.DateCalendarType = oldCC.DateCalendarType;
            }
            cc.SetPlaceholderText(null, null, "Editar");

            Microsoft.Office.Core.CustomXMLNode nodeMapping = customXMLPart.DocumentElement.SelectSingleNode(nodeXPath);
            cc.XMLMapping.SetMappingByNode(nodeMapping);
        }

        public static st_tipoTransacao ConverteAcessaDadosTipoTransacaoParaST_TipoTransacao(AcessaDadosBD.TipoTransacao tipoTransacao)
        {
            switch (tipoTransacao)
            {
                case AcessaDadosBD.TipoTransacao.ENVIO_LOTE_GUIAS:
                    return st_tipoTransacao.ENVIO_LOTE_GUIAS;
                    break;
                case AcessaDadosBD.TipoTransacao.SOLIC_DEMONSTRATIVO_RETORNO:
                    break;
                case AcessaDadosBD.TipoTransacao.SOLIC_STATUS_PROTOCOLO:
                    break;
                case AcessaDadosBD.TipoTransacao.SOLICITACAO_PROCEDIMENTOS:
                    return st_tipoTransacao.SOLICITACAO_PROCEDIMENTOS;
                    break;
                case AcessaDadosBD.TipoTransacao.PROTOCOLO_RECEBIMENTO:
                    break;
                case AcessaDadosBD.TipoTransacao.SITUACAO_PROTOCOLO:
                    break;
                case AcessaDadosBD.TipoTransacao.RESPOSTA_SOLICITACAO:
                    break;
                case AcessaDadosBD.TipoTransacao.DEMONSTRATIVO_PAGAMENTO:
                    break;
                case AcessaDadosBD.TipoTransacao.DEMONSTRATIVO_ANALISE_CONTA:
                    break;
                case AcessaDadosBD.TipoTransacao.DEMONSTRATIVO_ODONTOLOGIA:
                    break;
                case AcessaDadosBD.TipoTransacao.CANCELAMENTO_GUIA_RECIBO:
                    break;
                case AcessaDadosBD.TipoTransacao.RE_APRESENTACAO_GUIA:
                    break;
                case AcessaDadosBD.TipoTransacao.CANCELA_GUIA:
                    break;
                case AcessaDadosBD.TipoTransacao.VERIFICA_ELEGIBILIDADE:
                    break;
                case AcessaDadosBD.TipoTransacao.SITUACAO_ELEGIBILIDADE:
                    break;
                case AcessaDadosBD.TipoTransacao.AUTORIZACAO_ODONTOLOGIA:
                    break;
                case AcessaDadosBD.TipoTransacao.SOLICITA_STATUS_AUTORIZACAO:
                    break;
                case AcessaDadosBD.TipoTransacao.STATUS_AUTORIZACAO:
                    break;
                case AcessaDadosBD.TipoTransacao.ENVIO_ANEXO:
                    break;
                case AcessaDadosBD.TipoTransacao.PROTOCOLO_RECEBIMENTO_ANEXO:
                    break;
                case AcessaDadosBD.TipoTransacao.COMUNICACAO_BENEFICIARIO:
                    break;
                case AcessaDadosBD.TipoTransacao.RECIBO_COMUNICACAO:
                    break;
                default:
                    break;
            }
            return st_tipoTransacao.ENVIO_LOTE_GUIAS;
        }
        #endregion

        #region Construtor
        static AddinUtils()
        {
            OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + AppDomain.CurrentDomain.BaseDirectory + "\\app_Data\\docTissBDv2.accdb;Persist Security Info=True");

            cmd = new OleDbCommand();
            cmd.Connection = connection;

            UsuarioID = -1;
            PrestadorNome = string.Empty;
            CPF_CNPJ = string.Empty;
            TipoPrestador = null;
        }
        #endregion
    }
}
